/*  File Name	: EpollReactor.h
 *  Author		: Pang Jiacai
 *	 E-mail		: 823960168@qq.com
 *  Created on	: 2012-3-22
 *  Description:
 */

#ifndef EPOLLREACTOR_H_
#define EPOLLREACTOR_H_
#include <map>
#include <sys/epoll.h>

#include "Header.h"
#include "HandleSet.h"
#include "SignalHanlder.h"
#include "ReactorImpl.h"

class SignalHanlder;
class TimerHeap;

class EpollReactor:public ReactorImpl
{
public:
	typedef std::map<int,EventHandler*> HandleMap;

	EpollReactor(int handle_size,int timer_heap_size,bool only_timer=false,SignalHanlder *sh=NULL);
	virtual ~EpollReactor();

	struct EventTuple
	{
		EventTuple(EventHandler *eh=0,ReactorMask mask =EventHandler::NULL_MASK);

		EventHandler *event_handler_;

		ReactorMask  mask_;

		bool is_register_;

		bool is_suspended_;
	};

	class HandlerRepository
	{
	public:
		HandlerRepository();

		virtual ~HandlerRepository();

		int open(int max_size);

		int close(void);

		int bind(int handle,EventHandler *eh,ReactorMask mask);

		int unbind(int handle);

		int unbind_all(void);

		int cur_size(void);

		int max_size(void);

		EventTuple *find(int handle);

		bool is_legal_handler(int handle);

	private:
		int cur_size_;

		int max_size_;

		EventTuple *handler_;

		RT_MUTEX lock_;
	};

	virtual int open(int handle_size,int timer_heap_size,SignalHanlder *sh=NULL,bool only_timer=false);

	virtual int close(void);

	virtual void run_status(int status=0);//reactor run status,1:start 2:stop

	virtual int get_run_status(void);//reactor run status,1:start 2:stop

	virtual int handle_events(int timeout=-1);

	virtual int register_handler(int handle,EventHandler *eh,ReactorMask mask);

	/**
	 * this function will call EventHandler::handle_close
	 * so,don't invoke it in EventHandler::handle_close
	 */
	virtual int remove_handler(int handle,EventHandler *eh,ReactorMask mask);

	virtual int register_signal(int signum,EventHandler *eh,bool replace_old,EventHandler *old_sh);

	virtual int remove_signal(int signal,EventHandler *eh);

	virtual long schudle_timer(EventHandler *eh,TimeValue delay,TimeValue interval);

	virtual int suspend_timer(long timer_id);

	virtual int resume_timer(long timer_id);

	virtual int cancel_timer(long timer_id);

	virtual int refresh_timer(long timer_id,TimeValue new_time);

	virtual int reactor_type(void);

	virtual RT_MUTEX &lock(void);

	short mask_to_epool_event(ReactorMask mask);

	int mask_ops(int handle, ReactorMask mask, int ops);

	int resume_handler(int handle);

private:

	int dispatch_event(void);

	int dispath_signal_event(void);

	int dispatch_timer_event(void);

	int dispatch_io_event(void);

	bool init_;

	int epoll_fd_;

	epoll_event epoll_event_;

	HandlerRepository handler_rep_;

	RT_MUTEX resume_handle_mutex_;

	HandleMap resume_handle_map_;

	SignalHanlder *sig_handler_;

	bool del_sig_handler_;

	TimerHeap *timer_heap_;

	RT_MUTEX reactor_lock_;

	int run_status_;

	bool only_timer_;
};

#endif /* EPOLLREACTOR_H_ */
